// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: donggu, jhkim

#pragma once

#include <memory>
#include <string>

#include "coin2/exchange/base/order/processor.h"

namespace coin2::feed::mgr::impl {
class FeedSubsystemManager;
}

namespace coin2::exchange::base::order {
class IOrderSubscriber;
}  // namespace coin2::exchange::base::order

namespace coin2::exchange::di {
class ConstantInjection;
}

namespace coin2::exchange::sim::order_v1 {

class BacktestingGateway;

using GetProductHolderFunc = coin2::exchange::base::order::GetProductHolderFunc;

class SimSubsystem : public coin2::exchange::base::order::IOrderSubsystem {
 public:
  SimSubsystem(
      const std::string& name,
      const MarketExchangeApi& mea,
      const coin2::exchange::di::ConstantInjection& ci,
      const coin2::exchange::order::OrderSystemConfig& oss_config,
      base::executor::ArchiveSyncExecutor* exec,
      coin2::exchange::base::order::IOrderSubscriber* callback,
      const coin2::exchange::order::PrivateSubscriberConfig& subscriber_config,
      GetProductHolderFunc get_product_holder);
  ~SimSubsystem() override;

  bool is_supporting_separate_pos() const override { return true; }
  bool is_sim_os() const final { return true; }
  coin2::exchange::base::order::BaseOrderGateway* gateway() override;
  coin2::exchange::base::order::BaseOrderProcessor& processor() override;
  void ConnectFeed(coin2::feed::mgr::impl::FeedSubsystemManager* fsm);
  bool is_ready() const override { return true; }
  coin2::exchange::base::order::OrderQuerier*
      GenOrderQuerierForSim(int64_t sim_account_id) final;

 private:
  std::unique_ptr<BacktestingGateway> bts_;
};

}  // namespace coin2::exchange::sim::order_v1
